﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TGJ_GGA
{
    public delegate Gene OneGeneManipulatorDelegate(Gene g1);
    public delegate Gene TwoGeneManipulatorDelegate(Gene g1, Gene g2);

    public class ManipulatorHandler
    {
        private List<Manipulator> Manipulators = new List<Manipulator>();
        private Random rnd = new Random();

        public void add(OneGeneManipulatorDelegate aFunk, double P,string Name)
        {
            OneManipulator OM = new OneManipulator();
            OM.Funk = aFunk;
            OM.probability = P;
            OM.name = Name;
            Manipulators.Add(OM);
        }

        public void add(TwoGeneManipulatorDelegate aFunk, double P, string Name)
        {
            TwoManipulator OM = new TwoManipulator();
            OM.Funk = aFunk;
            OM.probability = P;
            OM.name = Name;
            Manipulators.Add(OM);
        }

        //run trough all the functions added, and return the resulting gene.
        public Gene run(Gene g1, Gene g2)
        {
            Gene tempa = ByteArrayGA.CopyGene(g1);
            Gene tempb = ByteArrayGA.CopyGene(g2);
                     
            foreach (Manipulator m in Manipulators)
            {
                if (rnd.NextDouble() < m.probability)
                {
                    if (m is OneManipulator)
                    {
                        tempa = ((OneManipulator)m).Funk(tempa);
                    }
                    if (m is TwoManipulator)
                    {
                        tempa = ((TwoManipulator)m).Funk(tempa, tempb);
                    }
                }
            }
            return tempa;
        }
    }

    class Manipulator
    {
        internal string name;
        internal double probability;
    }

    class OneManipulator : Manipulator
    {
        internal OneGeneManipulatorDelegate Funk;
    }

    class TwoManipulator : Manipulator
    {
        internal TwoGeneManipulatorDelegate Funk;
    }

  
}
